

int cmd; 
int data;
void setup()
{
  pinMode(12,OUTPUT);//
  pinMode(11,OUTPUT);//
  pinMode(10,OUTPUT);//
  Serial.begin(115200);//设置串口波特率为115200
} 

/*********************************************
 * 读取串口指令和数据
 * 要求出口发送过来的数据以c为头，c后为char的命令，d后为int数据，支持-号，e为结束符
 * 如：c12d123e
 * 该函数请尽量放在主函数的循环体中
 * *cmd, *data 的值为转换后的数据
 * 返回值:当接收到的数据满足格式要求，且接收完毕，返回0 ，否则返回1
 ********************************************/
int ReadCmd(int *cmd,int *data){
	char c=0;
	static char uart_cin_cmd = 0;
	static int uart_cin_data = 0;
	static char uart_cin_status = 0;  //接受指令的状态 ，和下一个状态
	static int uart_cin_flag = 1;  //
	int uart_cin_fuhao_valid = 1;   //data符号（+-）有效标志位
	while(Serial.available() > 0)
	{
		c = char(Serial.read());
		// 状态机状态切换  -----  解析数据格式 ------
		switch(c){
			case('c'):uart_cin_status = (uart_cin_status==0)?1:0; uart_cin_cmd = 0;continue; //收到指令帧头 将标志设为1，准备接受 命令
			case('d'):{ //收到数据标志 将会读取数据的符号 + -
				if(uart_cin_status==1){
					uart_cin_status = 2;
					uart_cin_data = 0;
				}  else {
					uart_cin_status = 0;
				}
				continue;
			}
			case('e'):{
				if(uart_cin_status==2){
					uart_cin_status = 0;
					*cmd = uart_cin_cmd;
					*data =uart_cin_flag*uart_cin_data ;
					uart_cin_fuhao_valid = 1;
					uart_cin_flag=1;
					return 0;
				} // 接收到数据接收结束标椎   回到初始状态
			}
			default:break;
		}
		switch(uart_cin_status){
			case(1):{
				if(c>='0'&&c<='9')uart_cin_cmd=10*uart_cin_cmd+(c-'0') ;
				else uart_cin_status = 0;
				break;
			}
			case(2):{
				if(c>='0'&&c<='9')uart_cin_data=10*uart_cin_data+(c-'0') ;
				else if( c=='-' && uart_cin_flag ==1 && uart_cin_fuhao_valid==1 ) { uart_cin_flag = -1;uart_cin_fuhao_valid=0;}
				else uart_cin_status = 0;
				break;
			}
			default:{ //复位
				uart_cin_data = 0;
				uart_cin_flag = 1;
				uart_cin_cmd = 0; 
				uart_cin_fuhao_valid=1;
			}
		}
	}
	return 1;
}
//---------------------------------

int MCP4XXX_PIN_CS=12;
int MCP4XXX_PIN_DIN=11;
int MCP4XXX_PIN_SCK=10;

//RAw(Dn) = Rab*(256-Dn)/256 + Rw
//RBw(Dn) = Rab*(Dn)/256 + Rw
/**********************************
 * 函数名:MCP4XX_Pin(int pin, int ttl)
 * 功能：设置对应引脚的电平
 * @param1: 指定的引脚
 * 			MCP4XXX_PIN_CS
 * 			MCP4XXX_PIN_DIN
 * 			MCP4XXX_PIN_SCK
 **********************************/
void MCP4XX_Pin(int pin, int ttl){
	if(ttl == 0){
		digitalWrite(pin,LOW);
	} else {
		digitalWrite(pin,HIGH);
	}
}
/**********************************
 * 函数名:MCP4XXX_Delay
 * 功能：驱动延时函数
 **********************************/
void MCP4XXX_Delay(){
	//delay(1);  //延时ms
	delayMicroseconds(2); //延时us
}
/**********************************
 * 函数名:MCP4XXX_Init
 * 功能：初始化MCP4XXX
 **********************************/
void MCP4XXX_Init(){
	MCP4XX_Pin(MCP4XXX_PIN_CS , 1);
	MCP4XX_Pin(MCP4XXX_PIN_SCK, 0);
}
/**********************************
 * 函数名:MCP4XXX_Set
 * 功能：设置数字电位器RAw的值
 * @param1:设置的值 0-255
 **********************************/
void MCP4XXX_Set(int data){
	int i = 0;
	int cmd = 0X00000011; // 00010001 
	int sdata = ((cmd<<8) & 0x0000FF00) | (data & 0x000000FF);
	MCP4XX_Pin(MCP4XXX_PIN_SCK, 0);
	MCP4XXX_Delay();
	MCP4XX_Pin(MCP4XXX_PIN_CS , 0);
	MCP4XXX_Delay();
	for(i=0;i<16;i++){
		MCP4XX_Pin(MCP4XXX_PIN_DIN, sdata & 0x00008000);
		MCP4XXX_Delay();
		MCP4XX_Pin(MCP4XXX_PIN_SCK, 1);
		MCP4XXX_Delay();
		MCP4XX_Pin(MCP4XXX_PIN_SCK, 0);
		sdata=sdata<<1;
	}
	MCP4XXX_Delay();
	MCP4XX_Pin(MCP4XXX_PIN_CS , 1);
}


void loop()
{
  if(0 == ReadCmd(&cmd,&data)  ){
    Serial.print(cmd);
	Serial.print(" ");
    Serial.println(data);
	MCP4XXX_Set(data);
    delayMicroseconds(10);  //延时 us
  }
} 


